﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SdmxMl.Structure;
using SdmxMl.Manager;

namespace SdmxMl.Structure
{
    public class HierarchyRefChecker
    {
        private Dictionary<string, CodeListType> dico;
        private SmManager sm;
        private const string CODE_TAG = " Code: ";

        public IList<string> Check(HierarchyType hierarchy)
        {
            // Dictionary of refered codelist in hierarchy that are available in memory.
            sm = ReferenceManager.GetSmContainerImage();

            // Complete if codelist are missing in memory
            dico = new Dictionary<string, CodeListType>();
            foreach (CodelistRefType crt in hierarchy.CodelistRefList)
            {
                CodeListType clType = sm.GetArtefact(SdmxArtefactType.CodeLists, crt, true) as CodeListType;
                if (clType == null)
                    throw new ApplicationException("Unable to locate referred codelist: " + crt.FullIdent);

                dico.Add(crt.Alias, clType);
            }

            HashSet<string> missList = new HashSet<string>();
            CheckCodeExistence(hierarchy.CodeRefList, missList);
            return missList.ToList<string>().AsReadOnly();

        }

        private void CheckCodeExistence(CodeRefTypeList crList, HashSet<string> missList)
        {

            foreach (CodeRefType crChild in crList)
            {
                CodeListType clt = dico[crChild.CodelistAliasRef];
                if (clt.CodeList.LocateItem(crChild.CodeID) == null && missList.Contains(clt.FullIdent + CODE_TAG + crChild.CodeID) == false)
                    missList.Add(clt.FullIdent + CODE_TAG + crChild.CodeID);
                CheckCodeExistence(crChild.CodeRefList, missList);
            }
        }
    }
}
